#include "analysisform.h"
#include "ui_analysisform.h"
#include <QString>
#include <QDebug>
#include "qint64item.h"
#include "qrealitem.h"
#include "QList"
#include <QPolygonF>
#include <QRectF>
#include <QLineF>
#include <QPointF>

AnalysisForm::AnalysisForm(QWidget *parent) :
    QWidget(parent),
    m_ui(new Ui::AnalysisForm)
{
    m_ui->setupUi(this);
    this->m_currentStatPtr=NULL;
    connect(m_ui->tabWidget,SIGNAL(currentChanged(int)),this,SLOT(tabSwitch(int)));
    m_ui->StatementTable->setColumnCount(4);
    m_ui->StatementTable->setRowCount(0);
    QStringList StatementTableHeaders;
    StatementTableHeaders<<"Count"<<"Total time (ms)"<<"Min/Avg/Max"<<"Statement";
    m_ui->StatementTable->setHorizontalHeaderLabels(StatementTableHeaders);

    this->m_frequencyPlot = new QGraphicsScene();
    m_ui->frequencyGraph->setScene(this->m_frequencyPlot);
    this->m_historicPlot  = new QGraphicsScene();
    m_ui->timeGraph->setScene(this->m_historicPlot);
}
void AnalysisForm::doConnections()
{
    connect(m_ui->nrOfIntervals,SIGNAL(valueChanged(int)),this,SLOT(plotFrequency()));
    connect(this,SIGNAL(SIG_updateFrequency()),this,SLOT(reScaleFrequencyPlot()));
    connect(this,SIGNAL(SIG_updateHistoric()),this,SLOT(reScaleHistoricPlot()));
    connect(m_ui->maxTime,SIGNAL(valueChanged(double)),this,SLOT(plotHistoric()));
    connect(m_ui->maxTime_2,SIGNAL(valueChanged(double)),this,SLOT(plotFrequency()));
    connect(m_ui->minTime,SIGNAL(valueChanged(double)),this,SLOT(plotHistoric()));
    connect(m_ui->minTime_2,SIGNAL(valueChanged(double)),this,SLOT(plotFrequency()));
}
void AnalysisForm::clearAll()
{
    m_ui->StatementTable->clearContents();
    m_ui->StatementTable->setRowCount(0);
}

void AnalysisForm::addStatement(qint64 timesExecuted,qreal totalTime, QString minavgmax,QString statement)
{
    QTableWidgetItem *newItem;
    int row = m_ui->StatementTable->rowCount();
    //newItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled);
    m_ui->StatementTable->setRowCount(row+1);

    /*newItem = new QTableWidgetItem(QString::number(timesExecuted));
    newItem->setForeground(QBrush(Qt::black));
    m_ui->StatementTable->setItem(row, 0, newItem);*/
    QInt64Item* new64Item;
    new64Item = new QInt64Item(timesExecuted);
    new64Item->setFlags(Qt::ItemIsEnabled);
    //new64Item->setData(QTableWidgetItem(QString::number(timesExecuted));
    new64Item->setForeground(QBrush(Qt::black));
    m_ui->StatementTable->setItem(row, 0, new64Item);

    QRealItem* newrealItem;
    newrealItem = new QRealItem(totalTime);
    newrealItem->setFlags(Qt::ItemIsEnabled);
    newrealItem->setForeground(QBrush(Qt::black));
    m_ui->StatementTable->setItem(row, 1, newrealItem);


    newItem = new QTableWidgetItem(minavgmax);
    //newItem->setFlags(Qt::ItemIsEnabled);
    newItem->setForeground(QBrush(Qt::black));
    m_ui->StatementTable->setItem(row, 2, newItem);

    newItem = new QTableWidgetItem(statement);
    //newItem->setFlags(Qt::ItemIsEnabled);
    newItem->setForeground(QBrush(Qt::black));
    m_ui->StatementTable->setItem(row, 3, newItem);
}

AnalysisForm::~AnalysisForm()
{
    delete m_ui;
}

void AnalysisForm::toggleStatementSort(bool sortenabled)
{
    m_ui->StatementTable->setSortingEnabled(sortenabled);
}

void AnalysisForm::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        m_ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void AnalysisForm::setStatementStatistics(qint64 totalNumber,qint64 totalNumberDistinct)
{
    m_ui->nrOfStatements->setText(QString::number(totalNumber));
    m_ui->NrOfUniqueStatements->setText(QString::number(totalNumberDistinct));
}

void AnalysisForm::setDurationStatistics(qreal totalTime,qreal averageTime)
{
    m_ui->totalDurationTime->setText(QString::number(totalTime));
    m_ui->averageDurationTime->setText(QString::number(averageTime));
}

void AnalysisForm::tabSwitch(int newTab)
{
    int currentRow;
    qDebug()<<"Tab was switched. new tab is "<<newTab;
    if (newTab ==0) // back to the statement list
    {
    }
    else if (newTab==1) // historic plot
    {
        currentRow = m_ui->StatementTable->currentRow();
        if (currentRow>=0)
        {
            emit SIG_getHistoric( m_ui->StatementTable->item(currentRow,3)->data(Qt::DisplayRole).toString());
            //qDebug()<<"Show historic plot for row "<<currentRow;
        }
        else
            qDebug()<<"SELECT a row...";
    }
    else if (newTab==2) //Frequency plot
    {
        currentRow = m_ui->StatementTable->currentRow();
        if (currentRow>=0)
            emit SIG_getFrequency(m_ui->StatementTable->item(currentRow,3)->data(Qt::DisplayRole).toString());
        else
            qDebug()<<"SELECT a row...";
    }
}

void AnalysisForm::plotHistoric(Stat* statPtr)
{
    if (statPtr != NULL)
        this->m_currentStatPtr = statPtr;
    if (this->m_currentStatPtr == NULL)
        return;
    qDebug()<<"Start plotting historic data currentstat="<<this->m_currentStatPtr;
    //m_ui->maxTime->setValue( this->m_currentStatPtr->getMax() );
    //m_ui->minTime->setValue( this->m_currentStatPtr->getMin() );

    //qreal max = this->m_currentStatPtr->getMax();
    qreal max = m_ui->maxTime->value();
    qreal min = m_ui->minTime->value();

    // plot all the data
    this->m_historicPlot->clear();
    //QPolygonF poly;
    //poly <<QPointF(0,0);
    QPointF first(0,max-0);
    QPointF last;
    int i,reali;
    reali=0;
    for (i=0; i<this->m_currentStatPtr->nrOfPosts();i++)
    {
        //poly<<QPointF(i,max-this->m_currentStatPtr->at(i));
        last.setX(reali);
        if (this->m_currentStatPtr->at(i)<=max && this->m_currentStatPtr->at(i)>=min)
        {
            last.setY(max-this->m_currentStatPtr->at(i));
            this->m_historicPlot->addLine(QLineF(first,last));
            first=last;
            reali++;
        }
    }
    last.setX(reali-1);
    last.setY(max-0);
    this->m_historicPlot->addLine(QLineF(first,last)); // close

    //poly<<QPointF(i-1,0);
    //this->m_historicPlot->addPolygon(poly);
    qDebug()<<this->m_historicPlot->itemsBoundingRect();
    m_historicPlot->setSceneRect( this->m_historicPlot->itemsBoundingRect());
    QRectF tmp=this->m_historicPlot->sceneRect();
    tmp.setBottomLeft(tmp.bottomLeft()+QPointF(-5,5));
    tmp.setTopRight(tmp.topRight()+QPointF(5,-5));
    m_ui->timeGraph->fitInView(tmp);
    m_ui->timeGraph->show();
    emit this->SIG_updateHistoric();
}
void AnalysisForm::plotFrequency(Stat* statPtr)
{
    if (statPtr!=NULL)
        this->m_currentStatPtr = statPtr;
    if (this->m_currentStatPtr == NULL)
        return;
    //m_ui->maxTime_2->setValue( this->m_currentStatPtr->getMax() );
    //m_ui->minTime_2->setValue( this->m_currentStatPtr->getMin() );
    int nrOfIntervals = m_ui->nrOfIntervals->value();
    qDebug()<<"Start plotting frequency data";
    //qreal max = this->m_currentStatPtr->getMax();
    //qreal min = this->m_currentStatPtr->getMin();
    qreal max = m_ui->maxTime_2->value();
    qreal min = m_ui->minTime_2->value();
    qreal dist = (max-min)/ (qreal) nrOfIntervals;
    if (dist==0)
        dist = 1;
    QList<int> freq;

    int i,idx;
    for (i=0;i<nrOfIntervals;i++)
        freq.insert(i,0);
    //qDebug()<<max<<min<<dist;
    //qDebug()<<"size= "<<freq.size();
    for (i=0;i< this->m_currentStatPtr->nrOfPosts();i++)
    {
        if (this->m_currentStatPtr->at(i)<=max && this->m_currentStatPtr->at(i)>=min)
        {
            idx = ( this->m_currentStatPtr->at(i) - min) /dist;
            if (idx>= nrOfIntervals)
                idx = nrOfIntervals-1;
            else if (idx<0)
                idx=0;
            freq[idx]--; // we plot in the other direction, y goes down as it increases!
        }
    }
    // plot freq....
    this->m_frequencyPlot->clear();
    QRectF rectF;
    QPolygonF poly;
    //poly <<QPointF(0,0);
    for (int i=0; i<nrOfIntervals;i++)
    {
        //poly<<QPointF(i,freq.at(i));
        rectF.setRect(i,0,1,freq.at(i));
        this->m_frequencyPlot->addRect( rectF);
    }
    //poly<<QPointF(i-1,0);
    //this->m_frequencyPlot->addPolygon(poly);

    //qDebug()<<"scene rect"<<this->m_frequencyPlot->sceneRect();
    this->m_frequencyPlot->setSceneRect(this->m_frequencyPlot->itemsBoundingRect());
    //qDebug()<<"items boundingrect"<<this->m_historicPlot->itemsBoundingRect();
    //qDebug()<<"scene rect"<<this->m_frequencyPlot->sceneRect();
    m_ui->frequencyGraph->fitInView(this->m_frequencyPlot->sceneRect());
    m_ui->frequencyGraph->show();
    emit this->SIG_updateFrequency();
}

void AnalysisForm::reScaleHistoricPlot()
{
    m_historicPlot->setSceneRect( this->m_historicPlot->itemsBoundingRect());
    m_ui->timeGraph->fitInView(this->m_historicPlot->sceneRect());

    QRectF tmp=this->m_historicPlot->sceneRect();
    tmp.setBottomLeft(tmp.bottomLeft()+QPointF(-5,5));
    tmp.setTopRight(tmp.topRight()+QPointF(5,-5));
    m_ui->timeGraph->fitInView(tmp);

    m_historicPlot->update();
    m_ui->timeGraph->update();
}
void AnalysisForm::reScaleFrequencyPlot()
{
    this->m_frequencyPlot->setSceneRect(this->m_frequencyPlot->itemsBoundingRect());
    m_ui->frequencyGraph->fitInView(this->m_frequencyPlot->sceneRect());

    QRectF tmp=this->m_frequencyPlot->sceneRect();
    tmp.setBottomLeft(tmp.bottomLeft()+QPointF(-5,5));
    tmp.setTopRight(tmp.topRight()+QPointF(5,-5));
    m_ui->frequencyGraph->fitInView(tmp);

    m_ui->frequencyGraph->update();
    this->m_frequencyPlot->update();
}

void AnalysisForm::setMaxHistoric(qreal x)
{
    m_ui->maxTime->setMaximum(x);
    m_ui->minTime->setMaximum(x);
    m_ui->maxTime->setValue(x);
}
void AnalysisForm::setMinHistoric(qreal x)
{
    m_ui->minTime->setMinimum(x);
    m_ui->maxTime->setMinimum(x);
    m_ui->minTime->setValue(x);
}
void AnalysisForm::setMaxFrequency(qreal x)
{
    m_ui->maxTime_2->setMaximum(x);
    m_ui->minTime_2->setMaximum(x);
    m_ui->maxTime_2->setValue(x);
}
void AnalysisForm::setMinFrequency(qreal x)
{
    m_ui->minTime_2->setMinimum(x);
    m_ui->maxTime_2->setMinimum(x);
    m_ui->minTime_2->setValue(x);
}


